/* Actors are entities which can run around in the dungeon,
 * either controlled by a player (-> character entity) or
 * by the computer (-> monsters and companions).
 * 
 */
#ifndef ACTOR_H_
#define ACTOR_H_

#include "action.h"
#include "items.h"

typedef Action Input;

typedef enum {
	ACTOR_INVALID,
	ACTOR_CHARACTER,
	ACTOR_MONSTER
} ActorType;

typedef enum {
	CHARACTER_UNDEFINED,
	CHARACTER_STONE,
	CHARACTER_NECRO,
	CHARACTER_LIX,
	CHARACTER_NINJA,
	CHARACTER_LEAF,
	CHARACTER_KNIGHT,
	CHARACTER_MAGE,
	CHARACTER_LIZARD,
	CHARACTER_ANGEL
} CharacterType;

typedef enum { 
	MONSTER_UNDEFINED, // Monsters of this species are ignored by game logic
	MONSTER_SLIME,
	MONSTER_PORCUPINE,
	MONSTER_HAND,
	MONSTER_TURTLE,
	MONSTER_STATUE,
	MONSTER_MOTH,
	MONSTER_TREE,
	MONSTER_GOLEM
} MonsterType;

/* contains ingame information about a character controlled by a player */
typedef struct {
	CharacterType type;
	int owner;        // ID of the Player who controls the character or -1 == none
	Inventory inventory;
	int gold;         // current collected treasures in gold points
} Character;

/* contains ingame information about a monster */
typedef struct {
	MonsterType type;
	bool is_awake;    // true if the monster receives update() calls
} Monster;

typedef struct {
	ActorType type;
	
	int id;        // Every actor has a unique ID in a game instance
	Coord spawn;   // Spawn- or checkpoint where the actor respawns
	Coord coord;   // Current position in whole tiles
	Direction dir;
	int hp;
	int hp_max;
	int cooldown;  // in ticks. Some actions, like attacks, require this to be 0.
	int level;     // Only characters change their level
	
	Action action;
	Input intention;
	
	struct {
		int spriteset;
		int frame;
	} gfx;
	
	union { // type dependant detail info
		Character* character;
		Monster* monster;
	};
} Actor;

/*
 * Returns true if setting the actor's intention
 * will have immediate effect.
 */
bool actor_can_act (Actor* actor);

/*
 * Returns true if setting the actor's intention to a complex action
 * which causes cooldown will have immediate effect. The attack actions,
 * but also e.g. use item are affected.
 */
bool actor_can_attack (Actor* actor);

bool actor_is_alive (Actor* actor);

void actor_alloc_character (Actor* actor, int id, Coord coord, int hp, CharacterType type);
void actor_alloc_monster (Actor* actor, int id, Coord coord, int hp, MonsterType species, int weapon, int armor);
void actor_respawn (Actor* actor);
void actor_cleanup (Actor* actor);

#endif
